package org.snail.transport.protocol;

/**
 * snail消息头16个字节定长
 *
 * ****************************************************************************************************
 *                                          protocol
 *  ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐
 *       2   │   1   │    1   │     8     │      4      │
 *  ├ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┤
 *           │       │        │           │             │
 *  │  magic   sign    status   invokeId    body length                   body                       │
 *           │       │        │           │             │
 *  └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
 *
 * ****************************************************************************************************
 * + 2    magic,(short) 0xabcd。
 * + 1    消息标志位低地址4位用来表示消息类型request/response/heartbeat, 高地址4位用来表示序列化类型。
 * + 1    状态位, 设置请求响应状态。
 * + 8    invokeId。
 * + 4    消息体 body 长度, int 类型。
 *
 * Created by fish on 17/4/1.
 */
public class Header {

    /**
     * 协议头长度
     */
    public static final int HEAD_LENGTH = 16;

    /**
     * Magic
     */
    public static final short MAGIC = (short) (0xabcd) ;

    /**
     * sign 低地址4位
     */
    private byte messageType;

    /**
     * sign 高地址4位
     */
    private byte serializerType;

    /**
     * 响应状态码
     */
    private byte statusType;

    /**
     * invokeId, 用于映射 <id, request, response> 三元组
     */
    private long invokeId;

    /**
     * 消息体长度
     */
    private int bodyLength;

    public void setSign(byte sign) {
        // sign 低地址4位
        this.messageType = (byte) (sign & 0x0f);
        // sign 高地址4位, 先转成无符号int再右移4位
        this.serializerType = (byte) ((((int) sign) & 0xff) >> 4);
    }


    public byte getSign(){
        return (byte) ((serializerType << 4) + messageType);
    }

    public void setMessageType(byte messageType) {
        this.messageType = messageType;
    }

    public void setSerializerType(byte serializerType) {
        this.serializerType = serializerType;
    }

    public byte getMessageType() {
        return messageType;
    }

    public byte getSerializerType() {
        return serializerType;
    }

    public byte getStatusType() {
        return statusType;
    }

    public void setStatusType(byte statusType) {
        this.statusType = statusType;
    }

    public long getInvokeId() {
        return invokeId;
    }

    public void setInvokeId(long invokeId) {
        this.invokeId = invokeId;
    }

    public int bodyLength() {
        return bodyLength;
    }

    public void bodyLength(int bodyLength) {
        this.bodyLength = bodyLength;
    }

    @Override
    public String toString() {
        return String.format("tigerHeader{,messageType=%s,serializerType=%s,statusType=%s,invokeId=%s,bodyLength=%s}",
                messageType,serializerType,statusType,invokeId,bodyLength);

    }
}
